#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <net/if.h>

#include "proto.h"

int main(void)
{
	struct sockaddr_in laddr, raddr;
	socklen_t raddr_len;
	int ret;
	struct ip_mreqn imr;
	char buf[MSGSIZE] = {};

	int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (-1 == udp_socket) {
		perror("socket()");
		exit(1);
	}

	laddr.sin_family = AF_INET;
	inet_aton("0.0.0.0", &laddr.sin_addr);
	// 网络字节序
	laddr.sin_port = htons(RCV_PORT);
	if (-1 == bind(udp_socket, (struct sockaddr *)&laddr, sizeof(laddr))) {
		perror("bind()");
		goto ERROR;
	}

	// 加入到多播组
	inet_aton(GROUP_ADDR, &imr.imr_multiaddr);
	inet_aton("0.0.0.0", &imr.imr_address);
	imr.imr_ifindex = if_nametoindex("ens33");
	if (-1 == setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr))) {
		perror("setsockopt()");
		goto ERROR;
	}

	// 一定要初始化raddr_len
	raddr_len = sizeof(struct sockaddr_in);
	ret = recvfrom(udp_socket, buf, MSGSIZE, 0, (struct sockaddr *)&raddr, &raddr_len);
	if (-1 == ret) {
		perror("recvfrom()");
		goto ERROR;
	}
	// 调试语句
	printf("from ip:%s, from port:%d\n", inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));
	printf("msg:%s\n", buf);

	close(udp_socket);

	return 0;
ERROR:
	close(udp_socket);
	exit(1);
}




